;; The first three lines of this file were inserted by DrRacket. They record metadata ;; about the language level of this file in a form that our tools can easily process. #reader(lib "htdp-intermediate-lambda-reader.ss" "lang")((modname reachables-wed) (read-case-sensitive #t) (teachpacks ()) (htdp-settings #(#t constructor repeating-decimal #f #t none #f ()))) (require rackunit) (require "extras.rkt") ;; Node = Int ;; Int -> SetOfInt ;; GIVEN: an integer ;; RETURNS: the list of its successors in the implicit graph. ;; For this graph, this is always a set (no repetitions) (define (successors1 n) (if (<= n 0) empty (local ((define n1 (quotient n 3))) (list n1 (+ n1 5))))) (begin-for-test (check set-equal? (successors1 6) (list 2 7)) (check set-equal? (successors1 2) (list 0 5)) (check set-equal? (successors1 0) empty) (check set-equal? (successors1 5) (list 1 6)) (check set-equal? (successors1 1) (list 0 5))) (define (all-successors nodes) (foldr (lambda (node ans-for-rest) (set-union (successors1 node) ans-for-rest)) empty nodes)) (begin-for-test (check set-equal? (all-successors (list 2 6)) (list 0 5 2 7))) ;; reachable-in : Node Nat -> SetofNode ;; GIVEN: A node s and a nonnegint n, ;; RETURNS: the set of nodes reachable from s ;; in at most n steps. ;; STRATEGY: general recursion ;; HALTING MEASURE: n (define (reachable-in s n) (if (zero? n) (list s) (local ((define already-seen (reachable-in s (- n 1)))) (set-union already-seen (all-successors already-seen))))) ;; reachable : Node SetofNode -> SetOfNode ;; GIVEN: a node s and a set seen ;; WHERE: there are only a finite number of nodes ;; reachable from s ;; AND seen = (reachable-in s n) for some n. ;; RETURNS: the set of all nodes reachable from s. ;; STRATEGY: General Recursion ;; HALTING MEASURE: (# of nodes reachable from s) - (# of nodes in seen) (define (reachable s seen) (local ((define new-nodes (set-union seen (all-successors seen)))) (if (set-equal? seen new-nodes) seen (reachable s new-nodes)))) ;; reachable-nodes : Node -> SetOfNode ;; GIVEN: a node s ;; WHERE: there are only a finite number of nodes ;; reachable from s ;; RETURNS: the set of all nodes reachable from s. ;; STRATEGY: FUNCTION COMPOSITION ;; initialize the invariant. (define (reachable-nodes s) (reachable s (list s)) #;(begin-for-test (check set-equal? (reachable (list 30) 0) (list 30)) (check set-equal? (reachable (list 30) 1) (list 30 10 15)) (check set-equal? (reachable (list 30) 2) (list 30 10 15 3 8 5)))